using PK.Broadcaster;
using PKGames.MiniGames.Common.Scripts;
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using VoxelGame.Character;

namespace PKGames.MiniGames.VoxelGame.UI.GameUI.Scripts.GamePanel
{
	public class ToolSelectionUiController : UiStateController<ToolSelectionUiState>, IMessageSubscriber<ToolChangedMessage>, IMessageSubscriber<UsingToolMessage>
	{
		[SerializeField]
		private Button _toolSelectionMenuButton;

		[SerializeField]
		private Button _toolSelectionArrowButton;

		[SerializeField]
		private Transform _toolSelectionMenuTransform;

		[SerializeField]
		private ToolUi[] _toolUiList;

		[SerializeField]
		private CanvasGroup _toolsCanvasGroup;

		[SerializeField]
		private Image _closeMenuImage;

		[SerializeField]
		private Image _currentToolSelected;

		private static readonly Color WhiteClearColor = new Color(1f, 1f, 1f, 0f);

		private const float AnimationTime = 0.2f;

		private float _currentAnimationPercentage;

		private void Awake()
		{
			MessageBroadcaster.Instance.Subscribe<ToolChangedMessage>(this);
			MessageBroadcaster.Instance.Subscribe<UsingToolMessage>(this);
		}

		private void OnDestroy()
		{
			MessageBroadcaster.Instance.Unsubscribe<ToolChangedMessage>(this);
			MessageBroadcaster.Instance.Unsubscribe<UsingToolMessage>(this);
		}

		public void Setup()
		{
			_toolSelectionMenuButton.onClick.AddListener(OnSelectionMenuClicked);
			_toolSelectionArrowButton.onClick.AddListener(OnSelectionMenuClicked);
			ChangeToNextState(ToolSelectionUiState.Hidden);
			ToolUi[] toolUiList = _toolUiList;
			foreach (ToolUi toolUi in toolUiList)
			{
				toolUi.Setup(OnButtonClicked);
			}
		}

		private void OnButtonClicked(CharacterToolsController.ToolData.Tools toolType)
		{
			MessageBroadcaster.Instance.BroadcastMessage(new ChangeToolMessage(toolType));
		}

		private void OnSelectionMenuClicked()
		{
			if (base.UiState == ToolSelectionUiState.Shown || base.UiState == ToolSelectionUiState.HiddenToShownTransition)
			{
				TryChangingToNextState(ToolSelectionUiState.ShownToHiddenTransition);
			}
			else
			{
				TryChangingToNextState(ToolSelectionUiState.HiddenToShownTransition);
			}
		}

		protected override bool CanChangeToNextState(ToolSelectionUiState nextState)
		{
			switch (base.UiState)
			{
			case ToolSelectionUiState.Shown:
				return nextState == ToolSelectionUiState.ShownToHiddenTransition;
			case ToolSelectionUiState.Hidden:
				return nextState == ToolSelectionUiState.HiddenToShownTransition;
			case ToolSelectionUiState.HiddenToShownTransition:
				return nextState == ToolSelectionUiState.Shown || nextState == ToolSelectionUiState.ShownToHiddenTransition;
			case ToolSelectionUiState.ShownToHiddenTransition:
				return nextState == ToolSelectionUiState.Hidden || nextState == ToolSelectionUiState.HiddenToShownTransition;
			default:
				return false;
			}
		}

		protected override void UpdateUiAccordingToState(ToolSelectionUiState nextState)
		{
			switch (nextState)
			{
			case ToolSelectionUiState.Shown:
				OnShownState();
				break;
			case ToolSelectionUiState.Hidden:
				OnHiddenState();
				break;
			case ToolSelectionUiState.HiddenToShownTransition:
				OnHiddenToShownState();
				break;
			case ToolSelectionUiState.ShownToHiddenTransition:
				OnShownToHiddenState();
				break;
			}
		}

		private void OnShownState()
		{
			_toolsCanvasGroup.interactable = true;
			_toolsCanvasGroup.blocksRaycasts = true;
			_toolSelectionArrowButton.interactable = false;
			SetAnimationClip(1f);
		}

		private void OnHiddenState()
		{
			_toolsCanvasGroup.interactable = false;
			_toolsCanvasGroup.blocksRaycasts = false;
			_toolSelectionArrowButton.interactable = true;
			SetAnimationClip(0f);
		}

		private void OnShownToHiddenState()
		{
			_toolsCanvasGroup.interactable = false;
			_toolSelectionArrowButton.interactable = false;
			StartCoroutine(AnimateToolSelectionUi(_currentAnimationPercentage, 0f, delegate
			{
				TryChangingToNextState(ToolSelectionUiState.Hidden);
			}));
		}

		private void OnHiddenToShownState()
		{
			_toolsCanvasGroup.interactable = false;
			_toolSelectionArrowButton.interactable = false;
			StartCoroutine(AnimateToolSelectionUi(_currentAnimationPercentage, 1f, delegate
			{
				TryChangingToNextState(ToolSelectionUiState.Shown);
			}));
		}

		private IEnumerator AnimateToolSelectionUi(float fromPercentage, float toPercentage, Action onFinish)
		{
			AnimationCurve animationCurve = AnimationCurve.EaseInOut(0f, fromPercentage, 0.2f * Mathf.Abs(toPercentage - fromPercentage), toPercentage);
			for (float time = 0f; time < 0.2f; time += Time.deltaTime)
			{
				SetAnimationClip(animationCurve.Evaluate(time));
				yield return null;
			}
			onFinish.Fire();
		}

		private void SetAnimationClip(float percentage)
		{
			_currentAnimationPercentage = percentage;
			_currentToolSelected.color = Color.Lerp(Color.white, WhiteClearColor, percentage);
			_closeMenuImage.color = Color.Lerp(WhiteClearColor, Color.white, percentage);
			_toolsCanvasGroup.alpha = percentage;
			_toolSelectionArrowButton.image.color = Color.Lerp(Color.white, WhiteClearColor, percentage);
			Vector3 position = _toolSelectionMenuTransform.position;
			ToolUi[] toolUiList = _toolUiList;
			foreach (ToolUi toolUi in toolUiList)
			{
				toolUi.ToolTransform.position = Vector3.Lerp(position, toolUi.ToolTransform.parent.TransformPoint(Vector3.zero), percentage);
			}
		}

		public void OnMessageReceived(ToolChangedMessage message)
		{
			ToolUi[] toolUiList = _toolUiList;
			foreach (ToolUi toolUi in toolUiList)
			{
				toolUi.UpdateSelection(message.ToolTypeSelected);
				if (toolUi.ToolType == message.ToolTypeSelected)
				{
					_currentToolSelected.sprite = toolUi.ToolImage.sprite;
				}
			}
		}

		public void OnMessageReceived(UsingToolMessage message)
		{
			TryChangingToNextState(ToolSelectionUiState.ShownToHiddenTransition);
		}
	}
}
